import Enumerable, { IGrouping } from 'linq';

/*
 * 简单的分组计算
 * 如果只有一个字段需要计算，请使用该原子操作，该原子操作运行效率更高
 * 如果有多个字段需要分组计算，请使用原子操作`groupby`
 * @param data JSON数据
 * @param group_fields 分组的字段
 * @param calculate_field 计算的字段（**注：如果有多个字段需要分组计算，请使用原子操作`groupby`**）
 * @param method 计算的字段
 */
export default function groupby<T>(data: T[], group_fields: Array<keyof T>, calculate_field: keyof T, method: 'sum' | 'average' | 'max' | 'min', alias?: string) {
	const len = group_fields.length;
	if (len === 0) {
		return data;
	} else if (len === 1) {
		const group_field = group_fields[0];
		return Enumerable.from(data).groupBy((it) => {
			return it[group_field];
		}, (it) => {
			return it;
		}, (it, group: IGrouping<string, T>) => {
			const values = Enumerable.from(group.getSource());
			return {
				[group_field]: it,
				[alias || calculate_field]: values[method]((val: T) => {
					return val[calculate_field] as unknown as number;
				})
			} as T & { [field: string]: any; };
		}).toArray();
	} else {
		return Enumerable.from(data).groupBy((it) => {
			return JSON.stringify(group_fields.reduce((pre, cur) => {
				return {
					...pre,
					[cur]: it[cur]
				};
			}, {}));
		}, (it) => {
			return it;
		}, (it, group: IGrouping<string, T>) => {
			const item = JSON.parse(it);
			const values = Enumerable.from(group.getSource());
			return {
				...item,
				[alias || calculate_field]: values[method]((val: T) => {
					return val[calculate_field] as unknown as number;
				})
			} as T & { [field: string]: any; };
		}).toArray();
	}
}
